function oSecurityEngine(engine) {
  this.passport = new oSecurityEngine_Passport(engine);
  this.token = new oSecurityEngine_Token(engine);
  this.auth = new oSecurityEngine_Auth(engine);
}

// 初始化原型链，包括护照、令牌、鉴权
function oSecurityEngine_Passport(engine) {
  this.engine = engine;
}

function oSecurityEngine_Token(engine) {
  this.engine = engine;
}

function oSecurityEngine_Auth(engine) {
  this.engine = engine;
}

oSecurityEngine_Passport.prototype = {
  // web and app
  get: function (callback) {
    let o = this;

    this.engine.request.getAjax("POST", "json", this.engine.config.url + "/ESB/Security/OAuth2/Passport", true, {
      name: o.engine.passport.name, password: o.engine.passport.password, timespan: o.engine.passport.timespan
    }, function (data) {
      // alert(JSON.stringify(data.content));
      // 判断护照是否正确获取到
      if (!o.engine.tools.IsNullOrEmpty(data) && data.status.code == 200) {
        o.engine.passport.id = data.content.id;
        o.engine.passport.typeID = data.content.typeID;
        o.engine.passport.realName = data.content.realName;
        o.engine.passport.language = data.content.language;
        o.engine.passport.appKey = data.content.appKey;
        // 模板设置样式
        o.engine.template.choiceTheme(data.content.theme);
        // 设置权限
        o.engine.passport.authorization = data.content.authorization;

        // 如果为空，则给予赋值
        if (o.engine.tools.IsNullOrEmpty(o.engine.passport.project)) {
          o.engine.passport.project = o.engine.passport.authorization.project.split(',')[0];
        }
        // 如果为空，则给予赋值
        if (o.engine.tools.IsNullOrEmpty(o.engine.passport.building)) {
          o.engine.passport.building = o.engine.passport.authorization.building.split(',')[0];
        }
      }
      // 将请求数据回调给前段处理，里面包含所有状态的数据，通过内部的Status Code来识别。
      if (callback) {
        callback(data);
      }
    });
  },
  // getApplet : async function(callback){
  //   let o = this;
  //   let platformFlag = 1;
  //   let appletMethods = await this.engine.applet.appletMethods();
  //   if ('getLocation' in appletMethods) {
  //     platformFlag = 2;
  //   } else {
  //     platformFlag = 1;
  //   }
  //   let { openID } = JSON.parse(localStorage.getItem('userInfo'));
  //   let password = o.engine.passport.mobile + '_GUOdong'
  //   let now = Date.now();
  //   let passport = {
  //     password: o.engine.tools.md5(password + now),
  //     timespan: now,
  //     userIDOrOpenID: openID,
  //     platformFlag,
  //   };
  //   this.engine.request.getAjax("POST", "json", this.engine.config.url + "/charging_pile/applet/gettoken", true, passport,res => {
  //     if (!o.engine.tools.IsNullOrEmpty(res) && res.status.code == 200) {
  //       o.engine.passport.id = res.content.tokenData.passport.id;
  //       o.engine.passport.realName = res.content.tokenData.passport.realName;
  //       o.engine.passport.language = res.content.tokenData.passport.language;
  //       o.engine.passport.appKey = res.content.tokenData.passport.appKey;
  //       o.engine.passport.mobile = res.content.tokenData.passport.mobile;
  //       o.engine.passport.password = res.content.tokenData.passport.password;
  //       o.engine.passport.timespan = res.content.tokenData.passport.timespan;
  //       // 模板设置样式
  //       o.engine.template.choiceTheme(res.content.tokenData.passport.theme);
  //       // 设置权限
  //       o.engine.passport.authorization = res.content.tokenData.passport.authorization;
  //       o.engine.passport.token = res.content.tokenData.passport.token;
  //     }
  //     // 将请求数据回调给前段处理，里面包含所有状态的数据，通过内部的Status Code来识别。
  //     if (callback) {
  //       callback(res);
  //     }
  //   })
  //
  //
  // }
}
oSecurityEngine_Token.prototype = {
  // 获取Token，自动处理localstorage中的护照数据，并自我分析、处理、合规的前提下返回Token。
  // Token获取成功，会自动触发callback事件，否则不会处理。
  get: function (callback) {
    let o = this;
    // 获取Token，有效期为10分钟。
    this.engine.request.getAjax("GET", "json", this.engine.config.url + "/ESB/Security/OAuth2/Token/" + this.engine.passport.appKey, true, null,
      async function (data) {
        // 得到新的Token数据，如果有效，则更新当前的Passport数据。
        if (!o.engine.tools.IsNullOrEmpty(data) && data.status.code == 200) {
          o.engine.passport.token = data.content.passport.token;
        }

        // 处理完成后完整将返回结果回调，不管是正常的还是错误的，前端会处理。
        if (callback) {
          callback(data);
        }
      });
  },
  exists: function (callback) {
    // 获取Token，有效期为10分钟。
    this.engine.request.getAjax("GET", "json", this.engine.config.url + "/ESB/Security/OAuth2/Token/Exists/" + this.engine.passport.token, true, null,
      function (data) {
        // 处理完成后回调。
        if (callback) {
          callback(data);
        }
      });
  }
}
// 判断token是否合法
oSecurityEngine_Auth.prototype = {
  // 获取授权，判断Token是否存在，如果存在，则调用token.exist判断是否有效（Token应该和Passport一样，else返回错误包，而不是直接处理）
  // 如果不存在，则调用token.get获取新的token，如果创建token失败，说明appKey已经过期，提示【保存页面内容，并重新登录】。
  get: function (url, callback) {
    let o = this;
    // 如果护照数据存在token，则发起token验证，看是否存在
    // alert(url);
    if (!this.engine.tools.IsNullOrEmpty(this.engine.passport.token)) {
      //判断是否有效，如果有效则返回对应授权
      this.engine.request.security.token.exists(function (data) {
        // 返回200的时候data为当前token的完整数据包。
        if (!o.engine.tools.IsNullOrEmpty(data) && data.status.code == 200) {
          assemble();
        }
        // 如果鉴权失败，则执行补救验证。
        else {
          o.engine.tips.debug("Auth： Token不存在，返回：" + JSON.stringify(data));
          // token过期，重试token。
          o.engine.request.security.token.get(async function (token_data) {
            if (!o.engine.tools.IsNullOrEmpty(token_data) && token_data.status.code == 200) {
              o.engine.tips.debug("Auth： Token获取成功，返回：" + JSON.stringify(token_data));
              assemble();
            } else {
              o.engine.tips.debug("Auth： Token创建失败，准备重新申请Passport，返回：" + JSON.stringify(token_data));
              // 护照过期，这时需重新申请，为了防止密码账户错误导致请求护照死循环，故只尝试1次护照的重新申请。
              let judgeCode = [300009];
              let isApplet = await o.engine.tools.isApplet();
              // 如果是移动端 或 小程序端 则追加 300007 状态让程序自动重新获取护照
              if (o.engine.tools.isMobile() || isApplet) {
                //如果是手机端，支持硬件码变更重新尝试登陆获取appKey
                judgeCode.push(300007)
              }
              // 如果包含09或07，则
              if (judgeCode.includes(token_data.status.code)) {
                o.engine.request.security.passport.get(getPassportCallback)
                // if(isApplet){
                //   o.engine.request.security.passport.getApplet(getPassportCallback)
                // }else{
                //   // 重新申请护照 + 令牌，只重试1次，防止死循环。
                //   o.engine.request.security.passport.get(getPassportCallback);
                // }
              } else {
                // 进入此处说明护照根数据都没找到，肯定要重新登录了。。
                o.engine.tips.error(data);
                // 无力回天，护照都申请失败了，说明护照数据被篡改或用户修改了密码，必须重新登录了。
                // console.error("auth login:" + window.location.href);
                o.engine.router.jumplogin();
              }
            }
          });
        }
      });
    } else {
      // this.engine.tips.debug("Auth： Token为空。");
      // this.engine.request.security.token.get(function (data) {
      //   if (!o.engine.tools.IsNullOrEmpty(data) && data.status.code == 200) {
      //     assemble();
      //   } else {
      //     // 如果尝试获取还是失败，则直接返回错误状态。
      //     o.engine.tips.error(data);
      //     // 无力回天，Token获取需要依靠AppKey，失败说明护照申请失败，说明护照数据被篡改或用户修改了密码，必须重新登录了。
      this.engine.router.jumplogin();
      //   }
      // });
    }

    function getPassportCallback(passport_data) {
      if (passport_data.status.code == 200 || passport_data.status.code == 200) {
        o.engine.tips.debug("Auth： 护照创建成功，返回：" + JSON.stringify(passport_data));
        o.engine.request.security.token.get(function (token_create_data) {
          o.engine.tips.debug("Auth： Token创建成功，返回：" + JSON.stringify(token_create_data));
          assemble();
        });
      } else {
        o.engine.tips.debug("Auth：护照创建失败，返回：" + JSON.stringify(passport_data));
        o.engine.tips.error(passport_data);
        // 无力回天，护照都申请失败了，说明护照数据被篡改或用户修改了密码，必须重新登录了。
        o.engine.router.jumplogin();
      }
    }

    // 装配url并回调事件
    function assemble() {
      let auth_url = o.engine.config.url + url;
      auth_url += auth_url.indexOf("?") > 0 ? "&" : "?";
      auth_url += "access_token=" + o.engine.passport.token;
      callback(auth_url);
    }
  },
  /*
   }*/
}


export {
  oSecurityEngine
}


